﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using System.Windows;
using PSE.Deployment.Setup.Main;
using PSE.Deployment.SetupBase;
using PSE.Deployment.SetupBase.Parameter.Enums;
using PSE.Deployment.SetupBase.UI;
using PSE.Deployment.Util;

namespace PSE.Deployment.Setup.UI
{
    public partial class PreRequisites : BaseWizardWindow
    {
        #region Propriedades

        public List<SoftwarePrerequisites> Softwares { get; set; }
        public List<PermissionPrerequisites> Permissions { get; set; }

        #endregion

        #region Construtor

        public PreRequisites()
        {
            this.InitializeComponent();

            Softwares = new List<SoftwarePrerequisites>();
            Permissions = new List<PermissionPrerequisites>();

            AddSOPrerequisite();
            AddAdministratorUserPrerequisite();
            AddCertificatePrerequisite();
            CheckAllowNext();

            if (SetupMainFactory.GetInstance<PSEMain>().Parameter.SetupMode == SetupMode.Change)
                BtnPrevious.Visibility = Visibility.Collapsed;
        }

        #endregion

        #region Método de Habilitação do Botão Próximo
        private void CheckAllowNext()
        {
            this.AllowNext = (!(SetupMainFactory.GetInstance<PSEMain>().Parameter.Prerequisites.OperationSystem != PrerequisitesStatus.Ok || SetupMainFactory.GetInstance<PSEMain>().Parameter.Prerequisites.AdmnistratorUser != PrerequisitesStatus.Ok));
        }
        #endregion

        #region Métodos para Pré-requisito de Sistema Operacional
        private void AddSOPrerequisite()
        {
            SoftwarePrerequisites software = new SoftwarePrerequisites();
            software.Id = "SO";
            software.Item = "Sistema Operacional";
            software.Recomended = "Windows XP (SP2) / Vista / Server 2003 / Server 2008";
            software.Status = CheckSOPrerequisite();
            software.ToolTipMessage = GetSOToolTipMessage(software.Status);
            Softwares.Add(software);
        }
        private PrerequisitesStatus CheckSOPrerequisite()
        {
            //TODO:Verificar SO
            PrerequisitesStatus prerequisite;
            if (Windows.CheckVersion())
                prerequisite = PrerequisitesStatus.Ok;
            else
                prerequisite = PrerequisitesStatus.NotOk;

            SetupMainFactory.GetInstance<PSEMain>().Parameter.Prerequisites.OperationSystem = prerequisite;
            return prerequisite;
        }

        private string GetSOToolTipMessage(PrerequisitesStatus status)
        {
            string toolTipMessage = String.Empty;

            switch (status)
            {
                case PrerequisitesStatus.Ok:
                    toolTipMessage = "Pré-requisito atendido!";
                    break;
                case PrerequisitesStatus.NotOk:
                    toolTipMessage = "Não será possível criar instalar o PSE pois o Sistema Operacional não atende ao pré-requisito!";
                    break;

            }

            return toolTipMessage;
        }

        #endregion

        #region Métodos para Pré-requisito de Usuário Administrador
        private void AddAdministratorUserPrerequisite()
        {
            PermissionPrerequisites user = new PermissionPrerequisites();
            WindowsIdentity identity = WindowsIdentity.GetCurrent();
            user.Id = "User";
            user.Item = "Usuário Administrador (" + identity.Name + ")";
            user.Status = CheckAdministratorUserPrerequisite();
            user.ToolTipMessage = GetAdministratorUserToolTipMessage(user.Status);
            Permissions.Add(user);
        }

        private PrerequisitesStatus CheckAdministratorUserPrerequisite()
        {
            //Verificar Criação do certificado
            PrerequisitesStatus prerequisite;

            if (!PSE.Deployment.Util.User.CheckAdministratorUser())
            {
                prerequisite = PrerequisitesStatus.NotOk;
            }
            else
                prerequisite = PrerequisitesStatus.Ok;

            SetupMainFactory.GetInstance<PSEMain>().Parameter.Prerequisites.AdmnistratorUser = prerequisite;
            return prerequisite;
        }

        private string GetAdministratorUserToolTipMessage(PrerequisitesStatus status)
        {
            string toolTipMessage = String.Empty;

            switch (status)
            {
                case PrerequisitesStatus.Ok:
                    toolTipMessage = "Pré-requisito atendido!";
                    break;
                case PrerequisitesStatus.Warning:
                    toolTipMessage = "Usuário logado não é Administrador da máquina." + Environment.NewLine + "Para executar o Setup PSE o usuário precisa ter perfil de Administrador!";
                    break;

            }

            return toolTipMessage;

        }
        #endregion

        #region Métodos para Pré-requisito de Certificados
        private void AddCertificatePrerequisite()
        {
            PermissionPrerequisites certificate = new PermissionPrerequisites();
            certificate.Id = "Cert";
            certificate.Item = "Certificados";
            certificate.Status = CheckCertificatePrerequisite();
            certificate.ToolTipMessage = GetCertificateToolTipMessage(certificate.Status);
            Permissions.Add(certificate);
        }

        private PrerequisitesStatus CheckCertificatePrerequisite()
        {
            //Verificar Criação do certificado
            PrerequisitesStatus prerequisite;

            if (!PSE.Deployment.Util.Certificate.CheckAccess(StoreName.TrustedPeople))
            {
                prerequisite = PrerequisitesStatus.Warning;
            }
            else
                prerequisite = PrerequisitesStatus.Ok;

            SetupMainFactory.GetInstance<PSEMain>().Parameter.Prerequisites.Certificate = prerequisite;
            return prerequisite;
        }

        private string GetCertificateToolTipMessage(PrerequisitesStatus status)
        {
            string toolTipMessage = String.Empty;

            switch (status)
            {
                case PrerequisitesStatus.Ok:
                    toolTipMessage = "Pré-requisito atendido!";
                    break;
                case PrerequisitesStatus.Warning:
                    toolTipMessage = "Não será possível criar os certificados PSE pelo Setup!" + Environment.NewLine + "A política de segurança não permite este tipo de operação." + Environment.NewLine + Environment.NewLine + "Consulte o Manual para instalar os certificados manualmente após a instalação. " + Environment.NewLine + "Sem os certificados instalados corretamente, o sistema não funcionará!";
                    break;

            }

            return toolTipMessage;

        }
        #endregion

        #region Excecução de programas externos

        private void btnInformation_Click(object sender, RoutedEventArgs e)
        {

        }

        #endregion
    }

    #region Software Prerequisites

    public class SoftwarePrerequisites : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string prop)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged.BeginInvoke(this, new PropertyChangedEventArgs(prop), null, null);
        }

        private string _id;
        private string _item;
        private string _recomended;
        private PrerequisitesStatus _status;
        private string _toolTipMessage;
        private bool _hasLink;

        public string Id
        {
            get
            {
                return _id;
            }
            set
            {
                _id = value;
                this.OnPropertyChanged("Id");
            }
        }

        public string Item
        {
            get
            {
                return _item;
            }
            set
            {
                _item = value;
                this.OnPropertyChanged("Item");
            }
        }

        public string Recomended
        {
            get
            {
                return _recomended;
            }
            set
            {
                _recomended = value;
                this.OnPropertyChanged("Recomended");
            }
        }

        public PrerequisitesStatus Status
        {
            get
            {
                return _status;
            }
            set
            {
                _status = value;
                this.OnPropertyChanged("Status");
            }
        }

        public string ToolTipMessage
        {
            get
            {
                return _toolTipMessage;
            }
            set
            {
                _toolTipMessage = value;
                this.OnPropertyChanged("ToolTipMessage");
            }
        }

        public bool HasLink
        {
            get
            {
                return _hasLink;
            }
            set
            {
                _hasLink = value;
                this.OnPropertyChanged("HasLink");
            }
        }
    }

    #endregion

    #region Permission Prerequisites

    public class PermissionPrerequisites : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string prop)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged.BeginInvoke(this, new PropertyChangedEventArgs(prop), null, null);
        }

        private string _id;
        private string _item;
        private PrerequisitesStatus _status;
        private string _toolTipMessage;

        public string Id
        {
            get
            {
                return _id;
            }
            set
            {
                _id = value;
                this.OnPropertyChanged("Id");
            }
        }

        public string Item
        {
            get
            {
                return _item;
            }
            set
            {
                _item = value;
                this.OnPropertyChanged("Item");
            }
        }

        public PrerequisitesStatus Status
        {
            get
            {
                return _status;
            }
            set
            {
                _status = value;
                this.OnPropertyChanged("Status");
            }
        }

        public string ToolTipMessage
        {
            get
            {
                return _toolTipMessage;
            }
            set
            {
                _toolTipMessage = value;
                this.OnPropertyChanged("ToolTipMessage");
            }
        }
    }

    #endregion
}
